package a;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 * @description: ZIP解压与压缩
 * @author: jinzewang
 * @project_name: farmpost
 * @date: 2022/12/14 15:54
 */
public class ZIPUtils {

    /**
     * 读取zip文件名称
     *
     * @param path 读取的zip文件路径
     */
    public static void getFileName(String path) {
        List<String> fileNames = new ArrayList<>();
        try {
            //这里一定要带入格式，不然在读取zip文件的时候会存在问题
            ZipFile zipFile = new ZipFile(path, StandardCharsets.UTF_8);
            Enumeration<? extends ZipEntry> entries = zipFile.entries();
            while (entries.hasMoreElements()) {
                String fileName = entries.nextElement().getName();
                fileNames.add(fileName);
                System.out.println("文件名称： " + fileName);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 读取zip文件内容
     *
     * @param path zip文件路径
     */
    public static void readFile(String path) {
        StringBuffer sb;
        Map<String, String> ddlList = new HashMap<>();
        try {
            ZipFile zipFile = new ZipFile(path, StandardCharsets.UTF_8);//必须指明读取的各式，不是会存在问题***
            InputStream in = new BufferedInputStream(new FileInputStream(path));//按流的方式读取文件，输入到管道中
            ZipInputStream zp = new ZipInputStream(in);//字节流转换为压缩文件输入流，通常用来读取压缩文件
            ZipEntry ze;//定义文件条目
            Enumeration zipEnum = zipFile.entries();
            while (zipEnum.hasMoreElements()) {//判断是否还有元素
                ze = (ZipEntry) zipEnum.nextElement();//返回下一对象
                sb = new StringBuffer();
                if (ze.isDirectory()) {
                } else {
                    System.out.println("file - " + ze.getName() + " : " + ze.getSize() + " bytes");
                    long size = ze.getSize();
                    if (size > 0) {
                        BufferedReader bf = new BufferedReader(new InputStreamReader(zipFile.getInputStream(ze), StandardCharsets.UTF_8));//读取文件内容
                        String line;
                        while ((line = bf.readLine()) != null) {
                            sb.append(line);
                        }
                        //这里是对读取的文件内容进行处理
                        ddlList.put(ze.getName(), sb.toString());
                        bf.close();
                    }
                }
            }
            zp.closeEntry();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 解压zip
     *
     * @param zippath
     * @param resourcepath
     */
    public static void unzip(String zippath, String resourcepath) {
        //判断生成目录是否生成，如果没有就创建
        File pathFile = new File(resourcepath);
        if (!pathFile.exists()) {
            pathFile.mkdirs();
        }
        ZipFile zp = null;
        try {
            //指定编码，否则压缩包里面不能有中文目录
            zp = new ZipFile(zippath, StandardCharsets.UTF_8);
            //遍历里面的文件及文件夹
            Enumeration entries = zp.entries();
            while (entries.hasMoreElements()) {
                ZipEntry entry = (ZipEntry) entries.nextElement();
                String zipEntryName = entry.getName();
                InputStream in = zp.getInputStream(entry);
                String outpath = (resourcepath + "\\" +zipEntryName);
                //判断路径是否存在，不存在则创建文件路径
                File file = new File(outpath.substring(0, outpath.lastIndexOf(File.separator)));
                if (!file.exists()) {
                    file.mkdirs();
                }
                //判断文件全路径是否为文件夹,如果是,不需要解压
                if (new File(outpath).isDirectory())
                    continue;
                OutputStream out = new FileOutputStream(outpath);
                byte[] bf = new byte[2048];
                int len;
                while ((len = in.read(bf)) > 0) {
                    out.write(bf, 0, len);
                }
                in.close();
                out.close();
            }
            zp.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 压缩成zip
     *
     * @param inputFile
     * @param outputFile
     * @throws IOException
     */
    public static void zippark(String inputFile, String outputFile) throws IOException {
        //创建zip输出流
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(outputFile));
        //创建缓存输出流
        BufferedOutputStream bos = new BufferedOutputStream(out);
        File input = new File(inputFile);
        compress(out, bos, input, null);
        bos.close();
        out.close();//要注意关闭流，不是会导致最终结果出现问题
    }

    public static void compress(ZipOutputStream out, BufferedOutputStream bos, File input, String name) throws IOException {
        if (name == null) {
            name = input.getName();
        }
        //如果输入的文件名称为文件夹,需要遍历里面的文件及文件夹下文件遍历;如果是文件就只需要将该文件进行压缩
        if (input.isDirectory()) {
            File[] files = input.listFiles();

            if (files.length == 0) {//当该文件夹为空时,只需要将该目录存入压缩文件中即可
                out.putNextEntry(new ZipEntry(name + "/"));
            } else {
                for (int i = 0; i < files.length; i++) {
                    compress(out, bos, files[i], name + "/" + files[i].getName());
                }
            }
        } else {
            out.putNextEntry(new ZipEntry(name));
            FileInputStream fos = new FileInputStream(input);
            BufferedInputStream bis = new BufferedInputStream(fos);
            int len;
            byte[] bf = new byte[1024];
            while ((len = bis.read(bf)) != -1) {
                bos.write(bf, 0, len);
                bos.flush();
            }
            bis.close();
            fos.close();
        }
    }


}
